package jacidco;


import java.sql.*;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;


public class BaseDatos
{
    /** Usuario con permisos a la Base de Datos. */
    private String userName;
    /** Password del usuario para conexion a la Base de Datos. */
    private String clave;
    /** Ruta de conexion a la Base de Datos. */
    private String url;
    private Connection con;
    private Statement st;
    /** Campo que almacena los diferentes Querys realizados a la Base de Datos. */
    private String query;
    private String query2;
    /** ResulSet que almacena los datos recuperados en las sentencias SELECT. */
    private ResultSet rs;
    private int cod;
    private String cadena,cadena2;

    /**
     * Constructor por defecto de un Objeto tipo BaseDatos.
     */
    public BaseDatos()
    {

    }
    
    /**
     * Realiza la conexion inicial a la Base de Datos y abre la comunicacion
     * con el aplcativo.
     */
    public Connection conectar()
    {

        try
        {

            userName = "jacidco";
            clave = "Adminjacidco";
            url = "jdbc:mysql://localhost:3306/jacidco";
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            con = DriverManager.getConnection(url, userName, clave);

            return con;

        }
        catch (Exception ex)
        {

            Main.mensaje.advertencia("Conectando a la BD", ex);
            return con;
         }
    }

    /**
     * Cierra la conexion con la Base de Datos
     */
    public void cerrarConexion()
    {

        try
        {
            con.close();
            System.out.println("Conexion cerrada");

        }
        catch(Exception e)
        {
            Main.mensaje.advertencia("Cerrando Conexion", e);
        }
    }

    /**
     * Ejecuta procedimiento almacenado para inicializar la Base de Datos
     * con 1 registro en todas las tablas
     */
    public void initDB()
    {
        try 
        {
            query = "CALL InitDB;";
            
            st = con.createStatement();
            st.execute(query);
            
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Ejecuntando Procedimiento InitBD", ex);
        }
    }
    
    /**
     * Autenticacion de Usuario
     * Raliza la validacion de usuario y clave contra la Base de Datos
       
       @param user Nombre de Usuario
       @param pass Password del Usuario
     */
    public boolean Autenticar(String user, String pass)
    {
        query = "SELECT usuario,clave FROM usuarios WHERE usuario=\""+user+"\" AND clave=\""+pass+"\""; 
         
        try 
        {
            st = con.createStatement();
            rs = st.executeQuery(query);
            
            rs.next();
            
            cadena = rs.getString("usuario");
            cadena2 = rs.getString("clave");
            
            if(user.equals(cadena) && pass.equals(cadena2))
            {
                return true;   
            }
            else
            {
                return false;
            }
 
        } 
        catch (SQLException ex) 
        {
            
            if(rs == null)
            {
                Main.mensaje.errorSQL("Autenticando Usuario", ex);
            }
            return false;
        }
        
         
        
    }
        
    /**
     * Trae los nombres de los datos requeridos para llenar los combo Box
     * 
     * @param Nombre Coleccion que guarda los nombres de los registros existentes. Este valor es retornado
     * @param tabla  La tabla donde se realizara la consulta
     */
    public Vector muestraDatosComboBoxes(Vector Nombre, String tabla)
    {

        byte i = 0;
        
        query = "SELECT nombre FROM "+tabla+"";
        
        try 
        {        
            st = con.createStatement();
            rs = st.executeQuery(query);
            
            while(rs.next())
            {
                Nombre.add(i, rs.getString("nombre"));
                i++;
            }
            
            return Nombre;
            
        } catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Leyendo nombre del nivel", ex);
            return null;
        }
        
        

    }
      
    /**
     * 
     * 
     * @param codAfiliado
     * @param Dia
     * @param Mes
     * @param Ano 
     */
    public boolean guardaFechaNacimiento(int codAfiliado, String Dia, String Mes, String Ano)
    {
        query = "INSERT INTO nacimiento (afiliado_cod_afiliado,dia,mes,ano) "
                + "VALUES ("+codAfiliado+",\""+Dia+"\",\""+Mes+"\",\""+Ano+"\")";
        
        try 
        {
            st = con.createStatement();
            st.execute(query);
            
            return true;
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Guardando la Fecha de Nacimiento", ex);
            return false;
        }
        
        
    }
    
    /**
     * Guarda datos del alumno en la BD del Frame Inscripciones
     */
    public boolean guardarDatosAlumno(int Cod, int codNivel, String primerNombre, String segundoNombre, String primerApellido, 
                                    String segundoApellido, int cedula, String carrera, String institucion, String direccion, 
                                    int telCasa, int telOfi, long telCel, String mail, String empresa, String codJava, String foto)
    {
        
        query = "INSERT INTO afiliado (cod_afiliado,Nivel_cod_nivel,primer_nombre,segundo_nombre,primer_apellido,segundo_apellido,cedula,carrera,institucion,direccion,telefono_casa,telefono_ofi,telefono_cel,mail,empresa,cod_java,foto)"
                      + "VALUES (\""+Cod+"\",\""+codNivel+"\",\""+primerNombre+"\",\""+segundoNombre+"\",\""+primerApellido+"\",\""+segundoApellido+"\",\""+cedula+"\",\""+carrera+"\",\""+institucion+"\",\""+direccion+"\",\""+telCasa+"\",\""+telOfi+"\",\""+telCel+"\",\""+mail+"\",\""+empresa+"\",\""+codJava+"\",\""+foto+"\")";
        

        
        try 
        {             
            st = con.createStatement();
            st.executeUpdate(query);

            return true;
            
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Guardando datos del Afiliado", ex);
            
            return false;
        }
    }


    /**
     * Recupera todos los campos de la tabla afiliado para se mostrado en el Frame
     * de Actualizar Datos
     * 
     * @param cod Codigo del afiliado para traer todos los datos
     */
    public ResultSet buscaAfiliado(int cod)
    {
        query = "SELECT * FROM afiliado WHERE cod_afiliado = "+cod+"";

        try
        {
            st = con.createStatement();
            rs = st.executeQuery(query);

            return rs;

        }
        catch (SQLException ex)
        {
            Main.mensaje.errorSQL("Leyendo Datos del afiliado", ex);
            return null;
        }
    }

    /**
      * Trae el codigo de Nivel al cual pertenece el afiliado al momento de buscar datos
      * en el Frame ActualizaDatos y lo asigna al ComboBox para desplegar el nombre del nivel
      * 
     * @param Cod   Codigo del Afiliado a Buscar
      */
    public int selectNivelActualizar(int Cod)
    {
        cod = 0;

        query = "SELECT cod_nivel FROM nivel INNER JOIN afiliado ON afiliado.Nivel_cod_nivel=nivel.cod_nivel WHERE cod_afiliado ="+Cod+"";

        try
        {
            st = con.createStatement();
            rs = st.executeQuery(query);

            if(rs.next())
            {
                cod = Integer.parseInt(rs.getString("cod_nivel"));
                return cod;
            }
            else
            {
                return 0;
            }
        }
        catch (SQLException ex)
        {
            Main.mensaje.errorSQL("Leyendo Codigo del Nivel", ex);
            return 0;
        }

    }
    
    
    public boolean actualizaFechaNacimiento(int codAfiliado, String Dia, String Mes, String Ano)
    {
        query = "UPDATE nacimiento SET dia=\""+Dia+"\",mes=\""+Mes+"\",ano=\""+Ano+"\" "
                + "WHERE afiliado_cod_afiliado = "+codAfiliado+"";
        
        try 
        {
            st = con.createStatement();
            st.executeUpdate(query);
            
            return true;
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Actualizando Fecha Nacimiento", ex);
            return false;
        }
        
    }
    /**
     * Actualiza datos en la BD desde la Clase ActualizaDatosFrame
     */
    public boolean actualizaDatos(String codJava, String primerApe, String segundoApe, String primerNom, String segundoNom, int cedula, String institut, String carrera,
                                  String direccion, int telCasa, int telOfi, long telCel, String empresa, String mail, int codNivel, String foto, int COD)
    {
        query = "UPDATE afiliado SET cod_java=\""+codJava+"\",primer_apellido=\""+primerApe+"\",segundo_apellido=\""+segundoApe+"\",primer_nombre=\""+primerNom+"\",segundo_nombre=\""+segundoNom+"\""
                + ",cedula=\""+cedula+"\",institucion=\""+institut+"\",carrera=\""+carrera+"\",direccion=\""+direccion+"\",telefono_casa=\""+telCasa+"\""
                + ",telefono_ofi=\""+telOfi+"\",telefono_cel=\""+telCel+"\",empresa=\""+empresa+"\",mail=\""+mail+"\",Nivel_cod_nivel=\""+codNivel+"\",foto=\""+foto+"\" WHERE cod_afiliado="+COD+"";
        
        try 
        {
            st = con.createStatement();
            byte val = (byte) st.executeUpdate(query);
            return true;
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Actualizando Datos del Afiliado", ex);
            return false;
        }
        
    }
    
    /**
     * Guarda datos del nivel al ser creado en la Clase CreaNivelesFrame
     
       @param codNivel  Codigo del Nivel Creado
       @param nombre    Nombre del Nivel Creado
       @param descrip   Descripcion del Nivel Creado
     */
    public boolean insertNivel(int codNivel, String nombre, String descrip)
    {
        query = "INSERT INTO nivel(cod_nivel,nombre,descripcion) VALUES("+codNivel+",\""+nombre+"\",\""+descrip+"\")";
        
        try 
        {
            st = con.createStatement();
            st.executeUpdate(query);
            return true;
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Guardando Datos del Nivel", ex);
            return false;
        }
        
    }

    /**
     * Gurada Datos del usuario al ser creado en la Clase CreaUsuarioFrame
     */
    public boolean guardaDatodUsuario(byte codUser, String Nombre, String Apellido, String Usuario, String Clave)
    {
        query = "INSERT INTO usuarios (cod_usuario, nombre, apellido, usuario, clave)"
                + "VALUES ("+codUser+",\""+Nombre+"\",\""+Apellido+"\",\""+Usuario+"\",\""+Clave+"\")";

        try
        {
            st = con.createStatement();
            st.execute(query);

            return true;

        }
        catch (SQLException ex)
        {
            Main.mensaje.errorSQL("Guardando Datos del Usuario", ex);
            return false;
        }

    }

    /**
     * Consulta la Base de Datos para conocer el siguiente codio a ingresar
     * al crear Afiliado, Nivel, Usuario, Material y Pago.
     * 
     * @param code      Codigo de la Llave Primaria
     * @param table     Nombre de la tabla para realizar la busqueda
     */
    public int nextCode(String code, String table)
    {
        query = "SELECT MAX("+code+") AS COD FROM "+table+"";

        try
        {
            st = con.createStatement();
            rs = st.executeQuery(query);

            if(rs.next())
            {
                cod = Integer.parseInt(rs.getString("COD"));
                return cod;
            }
            else
            {
               return 0;
            }

        }
        catch (SQLException ex)
        {
            Main.mensaje.errorSQL("Leyendo Codigo", ex);
            return 0;
        }
    }

    
    /**
     * Realiza la insersion de datos del Material en la Base de Datos
     * 
     * @param codMaterial   Codigo del Material
     * @param Nombre        Nombre del Material
     * @param Descrip       Descripcion del Material
     * @return              Retorna 'true' si no se genera alguna Excepcion en el proceso, o 'false' si hay Excepcion
     */
    public boolean guardaDatosMaterial(int codMaterial, String Nombre, String Descrip)
    {
        query = "INSERT INTO material (cod_material,nombre,descripcion)"
                + "VALUES("+codMaterial+",\""+Nombre+"\",\""+Descrip+"\")";
        
        try 
        {
            st = con.createStatement();
            st.execute(query);
            
            return true;
        } 
        catch(SQLException ex) 
        {
            Main.mensaje.errorSQL("Guardando Datos del Material", ex);
            return false;
        }
        
    }
    
    
    /**
     * Realiza la insersion de datos del Pago en la Base de Datos
     * 
     * @param codPago   Codigo del Pago
     * @param Nombre    Nombre del Pago
     * @param Desc      Descripcion del Pago
     * @param Valor     Valor del Pago
     * @return          Retorna 'true' si no se presenta Excepcion al guardar datos, 'false' si hay Excepcion
     * @see Exception
     */
    public boolean guardaDatosPago(byte codPago, String Nombre, String Desc, int Valor)
    {
        
        query = "INSERT INTO pagos (cod_pago,nombre,descripcion,valor)"
                + "VALUES ("+codPago+",\""+Nombre+"\",\""+Desc+"\",\""+Valor+"\")";
        
        
        try 
        {
            st = con.createStatement();
            st.execute(query);
            
            return true;
            
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Guardando Datos del Pago", ex);
            return false;
        }

    }

    
    /**
     * Consulta el Valor de un pago determinado
     * 
     * @param Cod   el codigo del pago a consultar
     * @return      retorna el valor del pago consultado
     */
    public String consulatValorPago(int Cod)
    {
        query = "SELECT valor FROM pagos WHERE cod_pago = "+Cod+"";
        
        try 
        {
            st = con.createStatement();
            rs = st.executeQuery(query);
            
            rs.next();
            
            String nom = rs.getString("valor");
            
            return nom;
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Error leyendo Valor de pago", ex);
            return null;
        }
        
    }

    
    /**
     * 
     * @param Semestre 
     */
    public void inicializaDatosPagoRealizado(String Semestre)
    {
        int numA=0, numP=0;
        
        String query1 = "SELECT COUNT(cod_afiliado) AS No_Afiliados FROM afiliado";
        
        try 
        {
            st = con.createStatement();
            rs = st.executeQuery(query1); 
            rs.next();
            
            numA = Integer.parseInt(rs.getString("No_Afiliados"));


        } 
        catch (SQLException ex) {Main.mensaje.advertencia(""+ex);}
        
        String query2 = "SELECT COUNT(cod_pago) AS No_Pagos FROM pagos";
        
        try 
        {
            st = con.createStatement();
            rs = st.executeQuery(query2); 
            rs.next();
            
            numP = Integer.parseInt(rs.getString("No_Pagos"));

        } 
        catch (SQLException ex) {Main.mensaje.advertencia(""+ex);}

        //=====================================================================================================
        try
        {
            for(short i=1;i<numP;i++)
            {
                for(short j=1;j<numA;j++)
                {
                    query = "INSERT INTO pagos_afiliado (PAGOS_cod_pago,AFILIADO_cod_afiliado,estado,semestre)"
                            + "VALUES (\""+i+"\",\""+j+"\",\"Pendiente\",\""+Semestre+"\")";

                    try 
                    {
                        st = con.createStatement();
                        st.execute(query);

                        //return true;
                    } 
                    catch (SQLException ex) 
                    {
                        if(ex.toString().contains("com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry"))
                        {
                            //Main.mensaje.advertencia("El afiliado ya realizao este pago.");
                            
                        }
                        else
                        if(ex.toString().contains("com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'semestre' at row 1"))
                        {
                            Main.mensaje.advertencia("Año ingresado no valido");
                           
                        }
                        else
                        {
                            Main.mensaje.errorSQL("Guardando datos del pago realizado", ex);
                            
                        }
                    }
                }
                
        }
        }catch(Exception e){
            //return false;
            Main.mensaje.advertencia(""+e);
        }
        
    }
    
    /**
     * 
     * 
     * @param codAfiliado
     * @param Semestre
     * @param codPago 
     */
    public boolean actualizaPagosACancelado(int codAfiliado, String Semestre, int codPago, String Estado)
    {
        query = "UPDATE pagos_afiliado SET estado = \""+Estado+"\" "
                + "WHERE AFILIADO_cod_afiliado = "+codAfiliado+" AND semestre = \""+Semestre+"\" AND PAGOS_cod_pago = "+codPago+"";
        
        try 
        {
            st = con.createStatement();
            st.executeUpdate(query);
            return true;
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Actualizando el Pago", ex);
            return false;
        }
       
    }
    
    
    /**
     * Realiza la insersion de datos en la Base de Datos, sobre la entrega de Material a un afiliado
     *
     * @param codAfiliado   el Codigo del Afiliado
     * @param codMaterial   el Codigo del Material entregado
     * @param Estado        el estado en que se encuentra la entrega del Material
     * @return              retorna 'true' si no se presenta alguna excepcion, 'false' si hay excepcion
     */
    public boolean guardaDatosEntregaMaterial(int codAfiliado, int codMaterial, String Estado)
    {
        query = "INSERT INTO material_alumno(AFILIADO_cod_afiliado, MATERIAL_cod_material, estado)"
                + "VALUES("+codAfiliado+","+codMaterial+",\""+Estado+"\")";
        
        try 
        {
            st = con.createStatement();
            st.execute(query);

            return true;
        }
        catch (SQLException ex)
        {
            if(ex.toString().contains("com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry"))
            {
                Main.mensaje.advertencia("El Afiliado ya cuenta con este Material");
            }
            else
            {
                Main.mensaje.errorSQL("Guardando datos de la entrega de Material", ex);
            }
            return false;
        }
        
    }
    
    
     //==================================================================================================================================
    /*
     * CONSULTAS
     */
    //===================================================================================================================================
    
    
    public ResultSet consultaGeneral()
    {
        try 
        {
            query = "SELECT cod_afiliado,primer_nombre,primer_apellido,institucion,carrera,cod_java,nivel.nombre "
                  + "FROM afiliado "
                  + "INNER JOIN nivel ON nivel.cod_nivel = afiliado.NIVEL_cod_nivel "
                  + "ORDER BY cod_afiliado ASC";
            
            st = con.createStatement();
            rs = st.executeQuery(query);
            
            return rs;
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Error consultando afiliados", ex);
            return null;
        }
    }
    
    
    public ResultSet consultaxNivel(String Nombre)
    {
        
        try 
        {
            query =   "SELECT cod_afiliado,primer_nombre,primer_apellido,cod_java "
                    + "FROM afiliado "
                    + "INNER JOIN nivel ON nivel.cod_nivel = afiliado.NIVEL_cod_nivel "
                    + "WHERE nivel.nombre = \""+Nombre+"\"";
            
            st = con.createStatement();
            rs = st.executeQuery(query);
            
            return rs;
            
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Consultado nivel", ex);
            return null;
        }
    }
    
    
    public Vector cumpleanosMes()
    {

        int cap = Main.bd.nextCode("cod_afiliado","afiliado")+1;

        Vector fecha = new Vector(cap);
        
        try 
        {
            query = "SELECT mes FROM nacimiento";
            
            st = con.createStatement();
            rs = st.executeQuery(query);
            
            rs.next();
            
            while(rs.next())
            {
                fecha.add(rs.getString("mes"));
            }
            
            return fecha;
            
        } 
        catch (SQLException ex) 
        {
            return null;
        }
    }
    
    
     public ResultSet cumpleanosMes(int Cod)
    {
        
        
        try 
        {
            query = "SELECT cod_java,primer_nombre,primer_apellido,dia,mes,ano "
                    + "FROM afiliado "
                    + "INNER JOIN nacimiento ON nacimiento.afiliado_cod_afiliado = afiliado.cod_afiliado "
                    + "WHERE cod_afiliado = "+Cod+"";
            
            st = con.createStatement();
            rs = st.executeQuery(query);

            return rs;
            
        } 
        catch (SQLException ex) 
        {
            return null;
        }
    }
    
     
    public ResultSet pagosPendientes(String nombrePago)
    {
        query = "SELECT cod_java,primer_nombre,primer_apellido,semestre,nombre,estado FROM afiliado "
                + "LEFT  JOIN pagos_afiliado ON pagos_afiliado.AFILIADO_cod_afiliado = afiliado.cod_afiliado "
                + "LEFT  JOIN pagos ON pagos_afiliado.PAGOS_cod_pago = pagos.cod_pago "
                + "WHERE pagos_afiliado.estado = \"Pendiente\" AND pagos.nombre = \""+nombrePago+"\"";
        
        try 
        {
            st = con.createStatement();
            rs = st.executeQuery(query);
            
            return rs;
        } 
        catch (SQLException ex) 
        {
            Main.mensaje.errorSQL("Error Consultando Pagos Pendientes", ex);
            return null;
        }
        
    }
    
    public void delete(int cod){
        
        query = "DELETE FROM nacimiento WHERE afiliado_cod_afiliado = "+cod+"";
        query2 = "DELETE FROM afiliado WHERE cod_afiliado = "+cod+"";
        
        try {
            
            st = con.createStatement();
            
            st.executeUpdate(query);
            st.executeUpdate(query2);
            
            
            Main.mensaje.advertencia("Datos Eliminados Correctamente");
            
        } catch (SQLException ex) {
            
            Main.mensaje.errorSQL("Error Eliminando Registro", ex);
        }
        
        
        
        
    }
}


